#lang racket

(require "rename-mutable-pair-ops.rkt")

;(provide make-table insert! lookup print-table)

(define (assoc key records)
  (cond ((null? records) false)
        ((equal? key (car (car records))) (car records))
        (else (assoc key (cdr records)))))

(define (1d-lookup key table)
  (let ((record (assoc key (cdr table))))
    (if record
        (cdr record)
        false)))

(define (1d-insert! key value table)
  (let ((record (assoc key (cdr table))))
    (if record
        (set-cdr! record value)
        (set-cdr! table
                  (cons (cons key value) (cdr table))))))

(define (make-table)
  (list '*table*))

(define (print-table t)
  (print-list (cdr t)))

(define (make-one-key-seq-tab key-seq value)
  (cond ((null? (cdr key-seq)) (let ((tab (make-table)))
                                 (1d-insert! (car key-seq) value tab)
                                 tab))
        (else (let ((out-tab (make-table))
                    (in-tab (make-one-key-seq-tab (cdr key-seq) value)))
                (1d-insert! (car key-seq) in-tab out-tab)
                out-tab))))

(define (lookup key-seq table)
  (let ((record (1d-lookup (car key-seq) table)))
    (cond ((or (null? (cdr key-seq)) (eq? false record)) record)
          (else (lookup (cdr key-seq) record)))))

(define (insert! key-seq value table)
  (let ((record (1d-lookup (car key-seq) table)))
    (cond ((null? (cdr key-seq)) (1d-insert! (car key-seq) value table))
          ((eq? false record)
           (let ((in-tab (make-one-key-seq-tab (cdr key-seq) value)))
             (1d-insert! (car key-seq) in-tab table)))
          (else (insert! (cdr key-seq) value record)))))

(define tab (make-table))

(insert! (list 1 2 3) 'yo tab)

(insert! (list 1 2 4) 'test tab)

(print-list tab)